package pl.diagnoser.server.lpr;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import pl.diagnoser.client.formulas.DiagnoserHBFormula;
import pl.diagnoser.client.formulas.DiagnoserIFormula;
import pl.diagnoser.client.formulas.DiagnoserSFormula;
import pl.diagnoser.client.formulas.DiagnoserVFormula;

import lprlibrary.formula.B;
import lprlibrary.formula.H;
import lprlibrary.formula.Implication;
import lprlibrary.formula.S;
import lprlibrary.formula.V;
import lprlibrary.lpr.KnowledgeBase;

public class DiagnoserKnowledgeBase extends KnowledgeBase {
	
	public static String DEFECT_WITH = "defekt w postaci";
	public static String SYMPTOM = "symptom";
	public static String OBJECTS = "pacjent";
	public static String HAS = "ma";
	public static String KIND_OF = "rodzaj";
    public static String DEFECT = "defekt";
	
    public static String PROJECT_TITLE = "tytuł projektu";
    public static String INNOVATION = "innowacja";
    public static String USER = "U";
    public static String FITS = "pasuje";
    public static String CHOSEN = "wybrał";
    
    /*
	public static String CHOOSE_ARTICLE = "wybrał artykuł";
	public static String NO_CHOOSE_ARTICLE = "nie wybrał artykułu";
	
	public static String CHOOSE_DESCRIPTION = "wybrał opis";
	public static String NO_CHOOSE_DESCRIPTION = "nie wybrał opisu";
	
	public static String CHOOSE_REALIZATOR = "wybrał realizatora";
	public static String NO_CHOOSE_REALIZATOR = "nie wybrał realizatora";
	
	public static String CHOOSE_EXECUTOR = "wybrał wykonawce";
	public static String NO_CHOOSE_EXECUTOR = "nie wybrał wykonawcy";
	
	public static String CHOOSE_DATE = "wybrał termin realizacji";
	public static String NO_CHOOSE_DATE = "nie wybrał termin realizacji";
	
	public static String CHOOSE_KEYWORD = "wybrał słowo kluczowe";
	public static String NO_CHOOSE_KEYWORD = "nie wybrał słowa kluczowego";
	
	public static String CHOOSE_INNOVATION_NAME = "wybrał nazwę innowacji";
	public static String NO_CHOOSE_INNOVATION_NAME = "nie wybrał nazwy innowacji";
	
	public static String CHOOSE_PROJECT_TITLE = "wybrał tytuł projektu";
	public static String NO_CHOOSE_PROJECT_TITLE = "nie wybrał tytułu projektu";
	
	public static String CHOOSE_TARGET_PROJECT = "wybrał projekt celowy";
	public static String NO_CHOOSE_TARGET_PROJECT = "nie wybrał projektu celowego";
	
	public static String ARTICLE = "artykuł";
	public static String DESC = "opis";
	public static String DATE = "termin realizacji";
	
	public static String INNOVATION_NAME = "nazwa innowacji";
	public static String KEY_WORD = "słowo kluczowe";
	
	public static String REALIZATOR = "realizator";
	public static String EXECUTOR = "wykonawca projektu";
	public static String TARGET_PROJECT = "projekt celowy";
	
	public static String FITS1 = "pasuje1";
	public static String FITS2 = "pasuje2";
	public static String FITS3 = "pasuje3";
	public static String FITS4 = "pasuje4";
	public static String FITS5 = "pasuje5";
	public static String FITS6 = "pasuje6";
	public static String FITS7 = "pasuje7";
	public static String FITS8 = "pasuje8";
	public static String FITS9 = "pasuje9";
	
	public String getFitForAttribute(String attribute) {
		if(attribute.equals(KEY_WORD))
			return FITS1;
		else if(attribute.equals(DATE))
			return FITS2;
		else if(attribute.equals(REALIZATOR))
			return FITS8;
		else if(attribute.equals(EXECUTOR))
			return FITS9;
		else if(attribute.equals(DESC))
			return FITS5;
		else if(attribute.equals(ARTICLE))
			return FITS3;
		else if(attribute.equals(PROJECT_TITLE))
			return FITS7;
		else if(attribute.equals(INNOVATION_NAME))
			return FITS4;
		else if(attribute.equals(TARGET_PROJECT))
			return FITS6;
		else
			return "";
	}
	*/
    
	/**
	* H(Ekologiczna technologia regeneracji bentonitowych mas formierskich, innowacja, tytuł projektu):0.8:0.5
	*/
	public List<String> getDefectsList(boolean isSearchMode) {
		List<String> list = new ArrayList<String>();
		
		for (H formulaH : formulasH) {			
			if(isSearchMode) {
				if (formulaH.getContext().equals(PROJECT_TITLE) && formulaH.getObject2().equals(INNOVATION)) {
					list.add(formulaH.getObject1());
				}
			} else {
				if (formulaH.getContext().equals(KIND_OF) && formulaH.getObject2().equals(DEFECT)) {
					list.add(formulaH.getObject1());
				}
			}
		}
		return list;
	}
	
	public List<H> getSymptomsHFormulas() {
		List<H> hFormulas = new ArrayList<H>();
		H pattern = new H("X", "Y", DiagnoserKnowledgeBase.SYMPTOM);
        pattern.setObject1Variable(true);
        pattern.setObject2Variable(true);
        H[] formulas = getFormulasHMatchingToPattern(pattern);
        for (int i=0; i < formulas.length; i++) {
                hFormulas.add(formulas[i]);
        }
		return hFormulas;
	}
	
	public List<S> getSymptomsSFormulas() {
		List<S> sFormulas = new ArrayList<S>();
		S pattern = new S("X", "Y", DiagnoserKnowledgeBase.SYMPTOM);
        pattern.setObject1Variable(true);
        pattern.setObject2Variable(true);
        S[] formulas = getFormulasSMatchingToPattern(pattern);
        for (int i=0; i < formulas.length; i++) {
                sFormulas.add(formulas[i]);
        }
		return sFormulas;
	}
	
	public Set<String> getSecondLevelSymptoms() {
		Set<String> symptomsSet = new HashSet<String>();
		List<H> hFormulas = null;
		hFormulas = getSymptomsHFormulas();
		for(H formula: hFormulas) {
			symptomsSet.add(formula.getObject1());
		}
		return symptomsSet;
	}
	
	public Set<String> getSimilarSymptoms() {
		Set<String> symptomsSet = new HashSet<String>();
		List<S> sFormulas = null;
		sFormulas = getSymptomsSFormulas();
		for(S formula: sFormulas) {
			symptomsSet.add(formula.getObject1());
		}
		return symptomsSet;
	}
	
	public String getSymptomGeneralization(String secondLevelSymptom) {
		String symptom = new String();
		Set<String> secondLevelSymptomsSet = getSecondLevelSymptoms();    
        if (secondLevelSymptomsSet.contains(secondLevelSymptom)) {
        	H pattern = new H(secondLevelSymptom, "X", DiagnoserKnowledgeBase.SYMPTOM);
            pattern.setObject2Variable(true);
            H[] foundHFormulas = getFormulasHMatchingToPattern(pattern);
            symptom = foundHFormulas[0].getObject2();
        }
		return symptom;
	}
	
	public String getSimilarSymptom(String symptom) {
		String similarSymptom = new String();
		Set<String> similarSymptomsSet = getSimilarSymptoms();
		if (similarSymptomsSet.contains(symptom)) {
			S pattern = new S(symptom, "X", DiagnoserKnowledgeBase.SYMPTOM);
            pattern.setObject2Variable(true);
            S[] foundSFormulas = getFormulasSMatchingToPattern(pattern);
            similarSymptom = foundSFormulas[0].getObject2();
		}
		return similarSymptom;
	}
	
	public Set<Implication> getDefectWithImplications() {
		Set<Implication> implications  = new HashSet<Implication>();
		V pattern = new V("U", DiagnoserKnowledgeBase.DEFECT_WITH, "I");
        Implication[] implicationsArray = getImplicationsUnifyingWithPattern(pattern);
        for (int i=0; i< implicationsArray.length; i++) {
                implications.add(implicationsArray[i]);
        }
        return implications;
	}
	
	public List<DiagnoserHBFormula> getHBFormulas() {
		ArrayList<DiagnoserHBFormula> formulas = new ArrayList<DiagnoserHBFormula>();
		for (H h : formulasH) {
			formulas.add(new DiagnoserHBFormula("H", h.getObject1(),
					h.getObject2(), h.getContext(), 
					Double.toString(h.getDomination()), 
					Double.toString(h.getTypicality())));
		}
		for (B b : formulasB) {
			formulas.add(new DiagnoserHBFormula("B", b.getObject1(), b.getObject2(), Double.toString(b.getConfidence())));
		}
		return formulas;
	}
	
	public List<DiagnoserVFormula> getVFormulas() {
		ArrayList<DiagnoserVFormula> formulas = new ArrayList<DiagnoserVFormula>();
		for (V v : formulasV) {
			formulas.add(new DiagnoserVFormula(v.getObject(), v.getAttribute(), v.getValue(), Double.toString(v.getConfidence())));
		}
		return formulas;
	}
	
	public List<DiagnoserSFormula> getSFormulas() {
		ArrayList<DiagnoserSFormula> formulas = new ArrayList<DiagnoserSFormula>();
		for (S s : formulasS) {
			formulas.add(new DiagnoserSFormula( s.getObject1(), s.getObject2(), s.getContext(), Double.toString(s.getSimilarityRate())));
		}
		return formulas;
	}
	
	public List<DiagnoserIFormula> getIFormulas() {
		ArrayList<DiagnoserIFormula> formulas = new ArrayList<DiagnoserIFormula>();
		for (Implication i : formulasI) {
			ArrayList<String> tmpPremises = new ArrayList<String>();
			for(V p : i.getPremises()) {
				tmpPremises.add(p.toString());
			}
			formulas.add(new DiagnoserIFormula( tmpPremises, i.getConclusion().toString(), Double.toString(i.getStrength())));
		}
		return formulas;
	}
}
